﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;
using System.Diagnostics;

using FCNS.KeepMoney.Util;
using FCNS.KeepMoneyLibrary.Data;

namespace FCNS.KeepMoney.UI
{
    public class ListViewItemGtd
    {
        bool check = true;
        public bool Checked
        {
            get
            {
                return check;
            }
            set
            {
                check = value;
            }
        }

        Color color = Color.Empty;
        public Color Color
        {
            get
            {
                return color;
            }
            set
            {
                color = value;
            }
        }

        object tag = null;
        public object Tag
        {
            get
            {
                return tag;
            }
            set
            {
                tag = value;
            }
        }

        String text = string.Empty;
        public String Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
            }
        }

        GtdGroupField data = null;
        public GtdGroupField GroupField
        {
            get
            {
                Debug.Assert(data != null);
                return data;
            }
            set { data = value; }
        }
    }

    internal partial class Detail : Control
    {

        Bitmap _offBmp = null;
        Pen pen1;
        SolidBrush sb1;
        Image imgcheck, imguncheck;
        ListViewItemGtd selected = null;
        ArrayList items;
        int heightList;
        int heightItem;
        int scrollValue = 0;
        bool isFocused = true;

        internal Detail()
        {
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserMouse, true);
            this.SetStyle(ControlStyles.ResizeRedraw, false);
            this.SetStyle(ControlStyles.Opaque, true);

            InitializeComponent();

            this.textBox1.AutoSize = false;
            this.textBox1.Location = new System.Drawing.Point(40, 48);
            this.textBox1.Size = new System.Drawing.Size(80, 64);

            pen1 = new Pen(Color.Empty);
            sb1 = new SolidBrush(Color.Empty);
            items = new ArrayList();
            imgcheck = Properties.Resources._checked;
            imguncheck = Properties.Resources._unchecked;
        }
      
        private void Content_Resize(object sender, EventArgs e)
        {
            IsChangeText();
            Repaint2();
        }

        private void Content_MouseDown(object sender, MouseEventArgs e)
        {
            IsChangeText();
            int i = 0;
            int Y = e.Y + (scrollValue * heightItem);
            foreach (ListViewItemGtd item in items)
            {
                heightList = heightItem * i;
                if ((Y >= HeightList) && (Y < (HeightList + heightItem)))
                {
                    if (e.X < 23)
                    {
                        item.Checked = !item.Checked;
                        CheckedChanged(item);
                    }
                    else
                    {
                        selected = item;
                        OnSelectedChanged(this, null);
                        if (e.Clicks == 2)
                        {
                            EditLabel();
                        }
                    }
                    Repaint2();
                }
                i++;
            }
        }

        private void Content_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(_offBmp, 0, -(scrollValue * heightItem));
            if ((-(scrollValue * heightItem) + _offBmp.Height) < this.ClientRectangle.Height)
            {
                sb1.Color = Color.FromArgb(255, 255, 255, 255);
                e.Graphics.FillRectangle(sb1, new Rectangle(0, -(scrollValue * heightItem) + _offBmp.Height, this.ClientRectangle.Width, this.ClientRectangle.Height - (-(scrollValue * heightItem) + _offBmp.Height)));
            }
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            keyPressed = e.KeyCode;
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (keyPressed)
            {
                case Keys.Escape:
                    textBox1.Text = Selected.Text;
                    IsChangeText();
                    e.Handled = true;
                    break;
                case Keys.Enter:
                    IsChangeText();
                    e.Handled = true;
                    break;
            }
        }

        private void textBox1_Leave(object sender, EventArgs e)
        {
            IsChangeText();
        }

        Image GetResourceImage(string name)
        {
            Assembly assembly = System.Reflection.Assembly.GetCallingAssembly();
            //MessageBox.Show(assembly.GetManifestResourceNames().Length.ToString());
            //foreach (string ss in assembly.GetManifestResourceNames())
            //{
            //    MessageBox.Show(ss);
            //}
            System.IO.Stream s = assembly.GetManifestResourceStream("FCNS.Controls.ListView." + name);
            return Image.FromStream(s);
        }

        int Height2()
        {
            if (this.ClientRectangle.Height > heightList)
                return this.ClientRectangle.Height;
            return heightList;
        }

        void Repaint2()
        {
            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1)) return;
            if ((_offBmp == null) || (_offBmp.Height != Height2()) || (_offBmp.Width != this.ClientRectangle.Width))
            {
                if (_offBmp != null) _offBmp.Dispose();
                _offBmp = new Bitmap(this.ClientRectangle.Width, Height2());
            }
            Graphics _g = Graphics.FromImage(_offBmp);

            _g.Clear(Color.White);
         PaintWidget(_g);
            _g.Dispose();
            Paint2();
        }

        void Paint2()
        {
            if ((_offBmp == null) || (_offBmp.Height != Height2()) || (_offBmp.Width != this.ClientRectangle.Width))
            {
                Repaint2();
                return;
            }

            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1))
                return;

            IntPtr hwnd = new IntPtr();
            hwnd = this.Handle;
            Graphics drawingSurface = Graphics.FromHwnd(hwnd);
            drawingSurface.DrawImage(_offBmp, 0, -(scrollValue * heightItem));
            if ((-(scrollValue * heightItem) + _offBmp.Height) < this.ClientRectangle.Height)
            {
                sb1.Color = Color.FromArgb(255, 255, 255, 255);
                drawingSurface.FillRectangle(sb1, new Rectangle(0, -(scrollValue * heightItem) + _offBmp.Height, this.ClientRectangle.Width, this.ClientRectangle.Height - (-(scrollValue * heightItem) + _offBmp.Height)));
            }
            drawingSurface.Dispose();
        }

        void DrawFillVGradient(Graphics g_, Rectangle rect1, Color color1, Color color2)
        {
            System.Int32 r, g, b, a;
            for (int i = 0; i < rect1.Height; i++)
            {
                a = color2.A + ((((rect1.Height - 1) - i) * (color1.A - color2.A)) / (rect1.Height - 1));
                r = color2.R + ((((rect1.Height - 1) - i) * (color1.R - color2.R)) / (rect1.Height - 1));
                g = color2.G + ((((rect1.Height - 1) - i) * (color1.G - color2.G)) / (rect1.Height - 1));
                b = color2.B + ((((rect1.Height - 1) - i) * (color1.B - color2.B)) / (rect1.Height - 1));
                pen1.Color = Color.FromArgb(a, r, g, b);
                g_.DrawLine(pen1, rect1.Left, rect1.Top + i, rect1.Right - 1, rect1.Top + i);
            }
        }

        void PaintWidget(Graphics g)
        {
            Font font1 = new Font("Tahoma", 8);
            StringFormat align1 = new StringFormat();
            align1.Alignment = StringAlignment.Near;
            int i = 0;
            bool sel = false;
            heightItem = (font1.Height + 10);
            SolidBrush brush = new SolidBrush(Color.FromArgb(0,101,202));
            foreach (ListViewItemGtd item in items)
            {
                heightList = heightItem * i;

                if (item == selected)
                {
                    sel = true;
                    Rectangle rect5 = new Rectangle(0, heightList + 1, this.ClientRectangle.Width, heightItem - 1);
                    if (isFocused)
                    {
                        pen1.Color = Color.FromArgb(255, 61, 123, 218);
                        g.DrawLine(pen1, 0, heightList, this.ClientRectangle.Width, heightList);
                        DrawFillVGradient(g, rect5, Color.FromArgb(255, 89, 153, 229), Color.FromArgb(255, 31, 92, 207));
                        brush.Color = Color.FromArgb(0, 101, 202);
                        g.FillEllipse(brush, this.Width - 25, heightList+2, 20, 18);
                    }
                    else
                    {
                        pen1.Color = Color.FromArgb(255, 139, 139, 139);
                        g.DrawLine(pen1, 0, heightList, this.ClientRectangle.Width, heightList);
                        DrawFillVGradient(g, rect5, Color.FromArgb(255, 159, 159, 159), Color.FromArgb(255, 119, 119, 119));
                        brush.Color = Color.FromArgb(117,117,117);
                        g.FillEllipse(brush, this.Width - 25, heightList+2, 20, 18);
                    }
                }

                Rectangle destRect1;
                destRect1 = new Rectangle(1 + (23 - imguncheck.Width) / 2, 1 + heightList + ((heightItem - imguncheck.Height) / 2), imguncheck.Width - 2, imguncheck.Height - 2);
                sb1.Color = item.Color;
                g.FillRectangle(sb1, destRect1);
                Rectangle rect1 = new Rectangle((23 - imguncheck.Width) / 2, heightList + ((heightItem - imguncheck.Height) / 2), imguncheck.Width, imguncheck.Height);
                Rectangle rect2 = rect1;
                rect2.Y = rect1.Y + 1;
                rect2.Height = (rect1.Height / 2) - 2;
                DrawFillVGradient(g, rect2, Color.FromArgb(183, 255, 255, 255), Color.FromArgb(80, 255, 255, 255));
                Rectangle rect3 = rect2;
                rect3.Y = rect2.Bottom + 1;
                rect3.Height = rect1.Height - rect2.Height - 3;
                DrawFillVGradient(g, rect3, Color.FromArgb(80, 255, 255, 255), Color.FromArgb(177, 255, 255, 255));

                pen1.Color = item.Color;
                g.DrawLine(pen1, rect1.Left + 1, rect1.Top, rect1.Right - 2, rect1.Top);
                g.DrawLine(pen1, rect1.Left + 1, rect1.Bottom - 1, rect1.Right - 2, rect1.Bottom - 1);
                g.DrawLine(pen1, rect1.Left, rect1.Top + 1, rect1.Left, rect1.Bottom - 2);
                g.DrawLine(pen1, rect1.Right - 1, rect1.Top + 1, rect1.Right - 1, rect1.Bottom - 2);

                System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
                ia.SetWrapMode(WrapMode.Tile);
                destRect1 = new Rectangle((23 - imgcheck.Width) / 2, heightList + ((heightItem - imgcheck.Height) / 2), imgcheck.Width, imgcheck.Height);
                if (item.Checked)
                {
                    g.DrawImage(imgcheck, destRect1, 0, 0, imgcheck.Width, imgcheck.Height, GraphicsUnit.Pixel, ia);
                }
                else
                {
                    g.DrawImage(imguncheck, destRect1, 0, 0, imguncheck.Width, imguncheck.Height, GraphicsUnit.Pixel, ia);
                }
                ia.Dispose();

                if (item == selected)
                    sb1.Color = Color.FromArgb(255, 255, 255, 255);
                else
                    sb1.Color = Color.FromArgb(255, 0, 0, 0);

                //brush.Color = Color.FromArgb(210, 210, 245);
                //g.FillEllipse(brush, this.Width - 25, heightList + 5, 20, 13);
                g.DrawString(item.Text, font1, sb1, 21, heightList + 5, align1);
          //这里写数量的     // g.DrawString(item.GTData.GetGtdTaskCount().ToString(), font1, sb1, this.Width-19, heightList + 5, align1);
                i++;
            }
            heightList = (items.Count) * heightItem;
            font1.Dispose();
            brush.Dispose();
            align1.Dispose();
            if ((sel == false) && (items.Count > 0))
            {
                Selected = (ListViewItemGtd)items[0];
            }
        }

        public int HeightList
        {
            get
            {
                return heightList;
            }
            set
            {
                heightList = value;
            }
        }

        public int HeightItem
        {
            get
            {
                return heightItem;
            }
            set
            {
                heightItem = value;
            }
        }

        public ArrayList Items
        {
            get
            {
                return items;
            }
            set
            {
                if (value == null)
                    items.Clear();
                else
                    items = value;
            }
        }

        public int ScrollValue
        {
            get
            {
                return scrollValue;
            }
            set
            {
                IsChangeText();
                scrollValue = value;
                Repaint2();
            }
        }

        public ListViewItemGtd Selected
        {
            get
            {
                return selected;
            }
            set
            {
                if (selected != value)
                {
                    selected = value;
                    Repaint2();
                    SelectedChanged(this, null);
                }
            }
        }

        public void SelectItem(ListViewItemGtd item)
        {
            selected = item;
        }

        public void UpdateList()
        {
            Repaint2();
        }

        public bool IsFocused
        {
            get
            {
                return isFocused;
            }
            set
            {
                isFocused = value;
                Repaint2();
            }
        }

        public void CheckedChanged(ListViewItemGtd item)
        {
            if (OnCheckedChanged != null) OnCheckedChanged(item);
        }

        public void AfterLabelEdit(ListViewItemGtd item)
        {
            if (OnAfterLabelEdit != null) OnAfterLabelEdit(item);
        }

        public void SelectedChanged(object o, System.EventArgs e)
        {
            if (OnSelectedChanged != null) OnSelectedChanged(o, e);
        }

        public event EventHandler OnSelectedChanged;
        public event ItemHandler OnAfterLabelEdit;
        public event ItemHandler OnCheckedChanged;

        void IsChangeText()
        {
            if (textBox1.Visible == true)
            {
                if (Selected.Text != textBox1.Text)
                {
                    Selected.Text = textBox1.Text;
                    AfterLabelEdit(selected);
                }
                textBox1.Visible = false;
                Repaint2();
            }
        }

        public void EditLabel()
        {
            int i = 0;
            foreach (ListViewItemGtd item in items)
            {
                if (item == selected) break;
                i++;
            }
            textBox1.Left = 23;
            textBox1.Top = (i * heightItem) - (scrollValue * heightItem) + 1;
            textBox1.Height = heightItem - 2;
            textBox1.Width = this.ClientRectangle.Width - 24;
            textBox1.Visible = true;
            textBox1.Text = selected.Text;
            textBox1.SelectAll();
            textBox1.Focus();
        }

        private Keys keyPressed;

    }
}
